package com.huawei.demo;

import com.huaweicloud.sdk.ccm.v1.CcmClient;
import com.huaweicloud.sdk.ccm.v1.model.CreateCertificateAuthorityRequest;
import com.huaweicloud.sdk.ccm.v1.model.CreateCertificateAuthorityRequestBody;
import com.huaweicloud.sdk.ccm.v1.model.CreateCertificateAuthorityResponse;
import com.huaweicloud.sdk.ccm.v1.model.CrlConfiguration;
import com.huaweicloud.sdk.ccm.v1.model.DistinguishedName;
import com.huaweicloud.sdk.ccm.v1.model.ExportCertificateAuthorityCertificateRequest;
import com.huaweicloud.sdk.ccm.v1.model.ExportCertificateAuthorityCertificateResponse;
import com.huaweicloud.sdk.ccm.v1.model.ShowCertificateAuthorityRequest;
import com.huaweicloud.sdk.ccm.v1.model.ShowCertificateAuthorityResponse;
import com.huaweicloud.sdk.ccm.v1.model.Validity;
import com.huaweicloud.sdk.core.auth.GlobalCredentials;

public class CertificateAuthorityManagerDemo {

    public static void main(String[] args) {

        /*
         * 基础认证信息：
         * - ak: 华为云账号Access Key
         * - sk: 华为云账号Secret Access Key
         * - domainId: 华为云账号ID 详情见https://support.huaweicloud.com/productdesc-iam/iam_01_0023.html
         * - ccmEndpoint: 华为云CCM服务(PCA属于CCM下的微服务)的访问终端地址
         */
        String ak = "<AccessKey>";
        String sk = "<SecretAccessKey>";
        String domainId = "<DomainID>";
        String ccmEndpoint = "<CcmEndpoint>";

        // 1.准备访问华为云的认证信息，PCA为全局服务
        final GlobalCredentials auth = new GlobalCredentials()
                .withAk(ak)
                .withSk(sk)
                .withDomainId(domainId);

        // 2.初始化SDK，传入认证信息及CCM服务的访问终端地址
        final CcmClient ccmClient = CcmClient.newBuilder()
                .withCredential(auth)
                .withEndpoint(ccmEndpoint).build();
        // 3.创建CA
        String caId = createCa(ccmClient);
        if (caId == null) {
            return;
        }

        // 4.查看CA详情
        ShowCertificateAuthorityResponse response = showCa(ccmClient, caId);
        if (response != null) {
            // 查看CA的签名算法与状态
            System.out.println(response.getKeyAlgorithm());
            System.out.println(response.getStatus());
        }

        // 5.导出CA证书体
        ExportCertificateAuthorityCertificateResponse resp = exportCa(ccmClient, caId);
        if (resp != null) {
            // 查看证书体与证书链，pem格式。根证书证书链为null
            System.out.println(resp.getCertificate());
            System.out.println(resp.getCertificateChain());
        }
    }

    private static String createCa(CcmClient ccmClient) {
        // 1、构造请求参数
        // （1）需要创建的CA证书类型:ROOT（根CA）、SUBORDINATE（从属CA）
        String CAType = "ROOT";
        // （2）证书密钥算法
        String keyAlgorithm = "RSA2048";
        // （3）签名哈希算法
        String signatureAlgorithm = "SHA512";

        /*
         * （4）证书有效期定义
         * - type: 时间类型，可选："YEAR"、"MONTH"、”DAY“、"HOUR"
         * - value: 对应的值
         */
        Validity validity = new Validity();
        validity.setType("YEAR");
        validity.setValue(20);

        /*
         * （5）定义CA证书的唯一标识信息
         * - organization: 组织名称
         * - organizationalUnit: 部门名称
         * - country: 国家缩写，仅限两个字符，如中国-CN
         * - state: 省市名称
         * - locality: 城市名称
         * - commonName: CA名称（CN）
         */
        DistinguishedName subjectInfo = new DistinguishedName();
        subjectInfo.setOrganization("your organization");
        subjectInfo.setOrganizationalUnit("your organizational unit");
        subjectInfo.setCountry("CN");
        subjectInfo.setState("your state");
        subjectInfo.setLocality("your locality");
        subjectInfo.setCommonName("your CA name");

        /*
         * （6）吊销列表配置信息
         * - enabled: 是否启用CRL配置
         * - obsBucketName: OBS桶名称，用于发布CRL，需要已授权!!!，详情见
         *                  https://support.huaweicloud.com/usermanual-ccm/ccm_01_0016.html
         * - crlName: 证书吊销列表文件名，不传入时默认取CA ID作为文件名
         * - validDays: 证书吊销列表更新周期
         */
        CrlConfiguration crlConfiguration = new CrlConfiguration();
        crlConfiguration.setEnabled(false);
        crlConfiguration.setObsBucketName("your OBS buck name");
        crlConfiguration.setCrlName("your CRL file name");
        crlConfiguration.setValidDays(7);
        // （7）请求体各属性赋值
        CreateCertificateAuthorityRequestBody requestBody = new CreateCertificateAuthorityRequestBody();
        requestBody.setType(CAType);
        requestBody.setKeyAlgorithm(keyAlgorithm);
        requestBody.setSignatureAlgorithm(signatureAlgorithm);
        requestBody.setValidity(validity);
        requestBody.setDistinguishedName(subjectInfo);
        requestBody.setCrlConfiguration(crlConfiguration);
        // 2、构造请求体
        CreateCertificateAuthorityRequest request = new CreateCertificateAuthorityRequest().withBody(requestBody);
        // 3、开始发起请求
        CreateCertificateAuthorityResponse response;
        try {
            response = ccmClient.createCertificateAuthority(request);
        } catch (Exception e) {
            System.out.println("error info: " + e.getMessage());
            return null;
        }
        // 4、获取创建成功的证书的ID
        return response.getCaId();
    }

    private static ShowCertificateAuthorityResponse showCa(CcmClient ccmClient, String caId) {
        ShowCertificateAuthorityRequest request = new ShowCertificateAuthorityRequest().withCaId(caId);
        try {
            return ccmClient.showCertificateAuthority(request);
        } catch (Exception e) {
            System.out.println("error info: " + e.getMessage());
            return null;
        }
    }

    private static ExportCertificateAuthorityCertificateResponse exportCa(CcmClient ccmClient, String caId) {
        ExportCertificateAuthorityCertificateRequest request = new ExportCertificateAuthorityCertificateRequest()
                .withCaId(caId);
        try {
            return ccmClient.exportCertificateAuthorityCertificate(request);
        } catch (Exception e) {
            System.out.println("error info: " + e.getMessage());
            return null;
        }
    }
}
